(ns minify.ui
  (:require
    [asset-minifier.core :as m]
    [clojurefx.clojurefx :as fx]
    [clojurefx.factory :as f]
    [clojurefx.protocols :as fxp]
    [minify.protocals :as p]
    [minify.fx]
    [clojure.java.io :as io]
    [clojure.string :as s]
    [clojure.pprint :refer [pprint]])
  (:import (javafx.stage FileChooser FileChooser$ExtensionFilter DirectoryChooser)
           (javafx.scene Node Scene)
           (java.io File)))

(defn compress [^File source ^File target option]
  (let [sn (.getName source)
        i  (.lastIndexOf sn ".")
        [sn ext] [(subs sn 0 i) (subs sn i (count sn))]
        tn (str sn ".min" ext)
        t  (io/file target tn)]
    (if (.exists source)
      (do (m/minify
            {(.getPath t) (.getPath source)}
            {:optimization option})
          "success")
      (str (.getPath source) " not exists!"))))

(defn create []
  (f/load-fxml "fxml/ui.fxml"))

(defn config-ui! [^Node ui]
  (let [{:keys [optimization s_choice t_choice status
                s_input t_input
                b_compress b_reset] :as _ui-map} (fx/get-id-map ui)

        get-win (fn [] (-> ui (.getScene) (.getWindow)))

        fc      (FileChooser.)
        dc      (DirectoryChooser.)
        ef      (FileChooser$ExtensionFilter. "JS/CSS" ["*.js" "*.css"])]
    (-> fc (.getExtensionFilters) (.add ef))

    (doto optimization
      (p/set-items! [:simple :advanced])
      (fxp/set-value! :simple))

    (doto s_choice
      (fxp/set-action!
        (fn [_]
          (when-let [f (.showOpenDialog fc (get-win))]
            (fxp/set-value! s_input (.getPath f))
            (.setUserData s_input f)))))

    (doto t_choice
      (fxp/set-action!
        (fn [_]
          (when-let [f (.showDialog dc (get-win))]
            (fxp/set-value! t_input (.getPath f))
            (.setUserData t_input f)))))

    (doto b_reset
      (fxp/set-action!
        (fn [_]
          (fxp/set-value! s_input "")
          (fxp/set-value! t_input "")
          (.setUserData s_input nil)
          (.setUserData t_input nil))))

    (doto b_compress
      (fxp/set-action!
        (fn [_]
          (when-let [^File s (.getUserData s_input)]
            (let [^File t (or (.getUserData t_input) (.getParent s))
                  opt     (fxp/value optimization)
                  r       (compress s t opt)]
              (fxp/set-value! status (str r))))))))
  ui)

;(let [ui (ui)]
;  (pprint (conf-ui! ui)))

